package com.chenfan.magic.tags.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.chenfan.magic.base.Kv;
import com.chenfan.magic.constant.RuntimeConstant;
import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.entity.MQLModel;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.entity.TTLModel;
import com.chenfan.magic.resolver._MainResolver;
import com.chenfan.magic.tags.TagHttp;
import com.chenfan.magic.utils.FastJsonKit;
import com.chenfan.magic.utils.OkHttpUtil;
import com.chenfan.magic.utils.StringKit;
import com.chenfan.magic.utils.StringPool;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * template 标签处理器
 *
 * @author  周夕
 * @date 2020-02-26 18:21
 */
@Component
@AllArgsConstructor
public class TagHttpHandler {

    /**
     * 执行入口
     *
     * @param mqlModel
     * @param key
     * @return
     */
    public boolean execute(
            MQLModel mqlModel,
            Map<String, Object> idcRuntimePool,
            String key,
            Map<String, Object> paramMap,
            Map<String, Object> resMap,
            Map<String, Object> eofMap,
            Map<String, Object> resolveMap,
            Map<String, Object> attributeMap,
            Kv kv,
            TTLModel ttlModel
    ) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        String prefixKey = TagHttp.tagNames + "#" + key;
        ttlDetailModel.start(prefixKey);
        TagHttp httpModel = mqlModel.getHttp(key, idcRuntimePool, paramMap, attributeMap);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_PREFIXKEY, prefixKey);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESPOND, httpModel.getRespond());
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESULTKEY, httpModel.getResultKey());
        Map<String, Object> res = Maps.newHashMap();
        //防止引用检测
        String json = JSON.toJSONString(paramMap, SerializerFeature.DisableCircularReferenceDetect);
        Map<String, Object> pm = FastJsonKit.jsonstring2Map(json);
        pm.remove("#params");
        pm.remove("#context");

        res = run(idcRuntimePool, ttlModel, prefixKey, httpModel, paramMap);
        res.put("#params", pm);
        resMap.put(prefixKey, res);
        paramMap.putAll(attributeMap);
        paramMap.putAll(res);
        resolveMap.put(httpModel.getResultKey(), httpModel.getContext());

        ttlModel.getExecuter().put(ttlDetailModel.end());
        return true;
    }

    /**
     * http动态远程请求
     *
     * @param httpModel
     * @param paramMap
     * @return
     */
    public Map<String, Object> run(Map<String, Object> idcRuntimePool, TTLModel ttlModel, String prefixKey, TagHttp httpModel, Map<String, Object> paramMap) {
        Map<String, Object> res = Maps.newHashMap();
        String code = new _MainResolver().resolveScope(idcRuntimePool, ttlModel, prefixKey, httpModel, paramMap);
        try {
            String result = "";
            Map<String, String> param = Maps.newHashMap();
            if (StringKit.isNotBlank(code)) {
                param = FastJsonKit.jsonstring2Map(code);
            }
            if (StringPool.GET.equalsIgnoreCase(httpModel.getMethod())) {
                result = OkHttpUtil.get(httpModel.getUrl(), param);
            } else if (StringPool.POST.equalsIgnoreCase(httpModel.getMethod())) {
                result = OkHttpUtil.post(httpModel.getUrl(), param);
            } else if (StringPool.SSL.equalsIgnoreCase(httpModel.getMethod())) {
                result = OkHttpUtil.post(httpModel.getUrl(), param);
            } else {
                IdcEngineEntry.throwException(idcRuntimePool, null, "http动态远程请求Method类型异常! 可选值: GET, POST, SSL ... (Method => \"" + httpModel.getMethod() + "\")");
            }
            res.put(httpModel.getResultKey(), result);
            res.put("#context", code);
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, "http动态远程请求调度器异常! \n", e);
        }
        return res;
    }
}
